API GatewayからSQSのFIFOキューにメッセージをPOSTする
表題の構成を試す機会があったので、その手順をご紹介します。
(今回はコンソールでゴリゴリ作業していきます)
SQSの作成
まずはSQSのFIFOキューを作成しましょう。2020年7月9日にSQSもコンソールのデザインが新しくなり見やすくなりました。
キューに適当な名前を付けます。FIFOキューの場合は名前の最後に.fifo
をつける必要がある点に注意しましょう。
また、今回は「コンテンツに基づく重複削除」にチェックを入れました。これで自動的にSQS側で重複削除IDを付与してくれます。重複削除IDを自分で付けたい場合は、このチェックを外しておきます。
(後はデフォルトで作成しました)
FIFOキュー(myqueue.fifo)が作成できました。
API Gatewayに付与するIAM Roleの作成
次に、API GatewayからSQSへメッセージを送るためのIAMポリシーを作成します。
サービスはAPI Gatewayを選択してください。
そのまま次に進みましょう。
ロールの作成画面はそのまま次に進みましょう。
必要に応じてタグを付けてください。
名前をつけてIAM Roleを作成します。
作成できたらSQSへメッセージを送るポリシーを作成して付与します。
権限はsqs:SendMessage
だけでいいので、下記のようなポリシーとなります。
(今回はビジュアルエディタで作りました。AWSアカウントIDとSQSリソースの名前はご自分のものに変えてください)
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "sqs:SendMessage", "Resource": "arn:aws:sqs:ap-northeast-1:[Your AWS Account ID]:myqueue.fifo" } ] }
作成できました。
API Gatewayの作成
次にAPI Gatewayを作成しましょう。
今回は「REST API」を作ります。
適当なAPI名を付けて作成しましょう。(ここではmysqsapi
)
作成できたAPIに対して「リソースの作成」を行います。
適当なリソース名を付けて作成します。(ここではenqueue
)
つぎにメソッドを作成します。
メッセージをPOSTで送りたいので「POST」を選択しましょう。
チェックボタンを押して作成します。
次に、各種パラメータを指定してメソッドのセットアップを行います。
設定項目 | 設定内容 |
---|---|
統合タイプ | AWSサービス |
AWSリージョン | ap-northeast-1(利用リージョンに合わせてください) |
AWSサービス | SQS |
HTTPメソッド | POST |
アクションの種類 | パス上書きの使用 |
パス上書き | [対象のAWSアカウントID] / [送信先のキューの名前] |
実行ロール | API Gateway用に作成したIAM RoleのARN |
コンテンツの種類 | パススルー |
デフォルトタイムアウトの使用 | チェック(デフォルト) |
上記の設定ができたら「保存」しておきましょう。
次に「統合リクエスト」を設定します。
まずはSQSへメッセージをPOSTするために「HTTPヘッダー」を設定します。
設定項目 | 設定内容 |
---|---|
Content-Type | 'application/x-www-form-urlencoded' |
最後にマッピングテンプレートを追加します。
SQSの作成時に指定した通り、重複削除IDは自動で付与されますが、「メッセージグループIDは必須で、自分で付与する必要がある」ので、MessageGroupId
も受け取れるようにしておきましょう。
注:肝心のテンプレートの内容ですが実際は1行です。下記で2行になっているのは表示上の都合になります。
設定項目 | 設定内容 |
---|---|
リクエスト本文のパススルー | テンプレートが定義されていない場合(推奨) |
Content-Type | application/json |
テンプレート | Action=SendMessage&MessageGroupId=$input.params ('MessageGroupId')&MessageBody=$input.body |
テストしてみる
一通り設定できたので、ここで早速テストしてみます。
「クエリ文字列」と「リクエスト本文」を次のように入力してテストします。
メッセージグループIDは、テストのために簡単な「group1」という名前にしました。
クエリ文字列
MessageGroupId=group1
リクエスト本文
{ "data" : "test" }
無事にメッセージが送れたら画面右側のようにMessageId
などを含んだレスポンスが返ってきます。
SQSのキューにメッセージが入っているか確認してみましょう。
ポーリングしてみます。
メッセージが入っているのが分かりますね。
中身を確認してみましょう。メッセージグループIDが「group1」で入っていて、重複削除IDも自動で付与されています。
本文も、先程送ったリクエストボディの中身が入っていますね。
せっかくなので、APIのデプロイまでやってみます。
適当なステージ名を付けてデプロイします。
デプロイできました。
デプロイしただけなのでどこからでもアクセスできる状態ですが、このAPIにメッセージを送ってみます。
今回はIoTデバイスからのデータを想定したものを送ってみました。
curl -H 'Content-Type:application/json' \ -X POST -d '{"led":"on", "temp":"27.2"}' \ https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/test/enqueue?MessageGroupId=group1
次のようなレスポンスが返ってくればOKです。(jq
コマンドで整形したものになります)
{ "SendMessageResponse": { "ResponseMetadata": { "RequestId": "bca777e2-0873-525d-bab0-20631bc11509" }, "SendMessageResult": { "MD5OfMessageAttributes": null, "MD5OfMessageBody": "f00741b736a7f5bc40b9d3f343bbf2c4", "MD5OfMessageSystemAttributes": null, "MessageId": "59654fca-0c86-48fe-92a4-fab561399b5f", "SequenceNumber": "18854884546143471616" } } }
先程と同様にSQS側も確認してみましょう。確かに送ったデータが届いていることを確認できました。
参考にしたページ
今回はFIFO自体の動作検証までは行っていません。SQSのFIFOの詳細は下記の記事が分かりやすいです。
マッピングテンプレート作成時に、SQSへPOSTリクエストする詳細を確認するのに参考にしました。
SQSのFIFO機能は東京リージョンでも使えます。
最後に
API Gatewayから標準キューへ送るための情報はいくつか出てきますが、FIFOキューへ送るときの手順がなかったのでご紹介してみました。(やることはほとんど変わりませんが…)
なお、FIFOキューは標準キューよりもパフォーマンス要件が異なるため、ユースケースを見極めて採用いただければと思います。
この記事がどなたかのお役に立てれば幸いです。